package resilienceManager.qmul.gemom;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.io.File;
import java.util.Random;
import java.util.Vector;

import javax.swing.JTextArea;
import javax.swing.text.DefaultCaret;

import no.geosoft.cc.graphics.GSegment;
import no.geosoft.cc.graphics.GStyle;

/**
 * Scenario Class
 * 
 * A thread to simulate the scenario
 * 
 * send message, mirror Gbroker finding, Gbroker Broken down 
 * 
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */


public class Scenario extends Thread {


	private ScenarioManager currentFrame;
	//
	private File file;
	
	private scParser sp;
	// the number of gbroker
	int gn=0;
	Gbroker[] glist;
	
	// the number of missor gbroker
	int mgn=0;
	Gbroker[] mglist;
	
	// the number of publisher
	int pn=0;
	Publisher[] plist;

	Color colors[] = { Color.GREEN, Color.YELLOW,Color.MAGENTA ,Color.RED };
	
	double cap_th[]= { 100.00, 75.00, 50.00, 25.00};
	
	private int path_broken=0;
	
	private int node_broken=0;


	public Scenario(ScenarioManager f)
	{
		currentFrame=f;
	
	}

	public void setFile(File f){
		
		this.file=f;
		sp=new scParser(f);
		
		gn=sp.getNum("gbroker");
		
		pn=sp.getNum("publiser");
		
		glist=new Gbroker[gn];
		
		sp.getGB().copyInto(glist);
		
		plist=new Publisher[pn];
		
		sp.getPU().copyInto(plist);
		
		Vector<Integer> events=sp.getBP();
		
		path_broken=events.get(0);
		
		events=sp.getBN();
		
		node_broken=events.get(0);
		
		
	}
	
	/**
	 * According to the disjointed index
	 * find the potential Gbroker
	 * 
	 * */
	public void findMirror(){
		
	}

	/**
	 * 
	 * Draw the simulated network
	 * */
	public void draw()
	{
		NodeObject[] publishers=new NodeObject[pn];
		NodeObject[] gbrokers=new NodeObject[gn];
		
		
		int sx=1200;
		
		int sy=1200;
		
		int pst=sx/(pn+1);
		int py=sy/5*1;
		
		int gst=sx/(gn+1);
		int gy=sy/5*3;
		
		for(int i=0; i<pn; i++)
		{
			String ps="P"+(i+1);
			int px=150+i*pst;
			publishers[i] = new NodeObject (ps, currentFrame.scene_, px, py,1);
			publishers[i].draw();
			

		}	

		for(int j=0; j<gn; j++)
		{
			String gs="G"+(j+1);
			int gx=200+j*gst;
			gbrokers[j]= new NodeObject (gs,currentFrame.scene_,gx,gy,glist[j].getCAP());		
			gbrokers[j].draw();
			
		}
		
		RectObject timeRect=getTime(0);
		timeRect.draw();
		
		currentFrame.scene_.refresh();
		currentFrame.scene_.removeAll();
		currentFrame.scene_.draw();
		
		
	}
	
	/**
	 * 
	 * 
	 * */
	private RectObject getTime(int i)
	{
		RectObject timeRect =new RectObject(""+i,currentFrame.scene_, 1090,10,100,50 );
		//timeRect.draw();
		GSegment g=timeRect.getSegment();
		
		GStyle style = g.getOwner().getStyle();
		style.setBackgroundColor(Color.BLUE);
		
		return timeRect;
	}
	
	private void EventAction(int ts)
	{
		
		if(ts==path_broken)
		{
			
		}
		
		if(ts==node_broken)
		{
			/*NSPartitioner app = new NSPartitioner();

			Random r = new Random();
			int gid=r.nextInt(gn);
			while(gid<=0)
			{
				gid=r.nextInt(gn);
			}
			app.SetGB(glist, gid);
			
			currentFrame.textField.append("Gbroker"+gid+" is broken down\n");
			
			currentFrame.pauseAction();
			*/
		}
	}

	public void Scupdate(int ts)
	{

		NodeObject[] publishers=new NodeObject[pn];
		NodeObject[] gbrokers=new NodeObject[gn];

		int sx=1200;
		
		int sy=1200;
		
		int pst=sx/(pn+1);
		int py=sy/5*1;
		
		int gst=sx/(gn+1);
		int gy=sy/5*3;

		for(int i=0; i<pn; i++)
		{
			String ps="P"+(i+1);
			int px=150+i*pst;
			publishers[i] = new NodeObject (ps, currentFrame.scene_, px, py,1);
			publishers[i].draw();	

		}
		
		for(int i=0; i<gn; i++)
		{
						
			Random r = new Random();
			int sid=r.nextInt(pn);
			double sp=plist[sid].getSpeed();
			
			String gs="G"+(i+1);
			int gx=200+i*gst;
			gbrokers[i]= new NodeObject (gs,publishers[sid],gx,gy,glist[i].getCAP());
			
			String append="Publisher("+(sid+1)+") send a message to Gbroker ("+(i+1)+")\n";
			
			currentFrame.textField.append(append);
		

			
			glist[i].setNS(sp, ts);
			checkColor(gbrokers[i], i);
			
			gbrokers[i].draw();

			
		}
		// update the time 
		RectObject timeRect=getTime(ts);
		timeRect.draw();

		currentFrame.scene_.refresh();
		currentFrame.scene_.removeAll();
		currentFrame.scene_.draw();
		
		EventAction(ts);

	}
	
	public void changeColor(NodeObject n,int st)
	{
		GSegment g=n.getSegment();
		
		GStyle style = g.getOwner().getStyle();
	    if (style == null) return;
	   
	    style.setBackgroundColor(colors[st]);
	    
	    
	}
	
	public void checkColor(NodeObject n, int id)
	{
		
		double cap=glist[id].getState();
		
		switch ((int)cap/25){
		case 0:
			changeColor(n,0);
			break;
		case 1:
			changeColor(n,1);
			break;
		case 2:
			changeColor(n,2);
			break;
		case 3:
			changeColor(n,3);
			break;
		default:
			changeColor(n,3);
			break;
		}
		
	}


	public void run() {
		try {
			Scupdate(0);
			for (int i = 1; i <= 1000; i++) {
				Scupdate(i);
				sleep(1000);
			}
		} catch (InterruptedException e) {

			e.printStackTrace();
		}


	}


}
